using System;
using System.Collections.Generic;
using System.Windows.Controls;
using FireStarterModeller.UI.DetailsView.Controller;
using Habanero.Base;
using Habanero.Base.Exceptions;

namespace FireStarterModeller.UI.DetailsView.WPF
{
    /// <summary>
    /// Interaction logic for SolutionView.xaml
    /// </summary>
    public partial class SolutionView : UserControl
    {
        private readonly List<SolutionAssemblyView> _assemblyViews;
        private RenameItemPopup _renameAssemblyPopup;
        private NewItemPopup _newAssemblyPopup;

        public SolutionView()
        {
            InitializeComponent();
            _assemblyViews = new List<SolutionAssemblyView>();
        }

        public void Init(ISolutionViewController controller, SolutionViewModel model)
        {
            Controller = controller;
            Model = model;
            foreach (SolutionViewModel.AssemblyModel assemblyModel in Model.Assemblies)
            {
                AddAssemblyView(assemblyModel);
            }

            model.CurrentAssemblyChanged += assemblyModel =>
                                            {
                                                foreach (SolutionAssemblyView view in _assemblyViews)
                                                {
                                                    view.IsSelected = view.Model == assemblyModel;
                                                }
                                            };
            model.AssemblyAdded += AddAssemblyView;
            model.AssemblyRemoved += RemoveAssemblyView;
            _renameAssemblyPopup = new RenameItemPopup();
            _renameAssemblyPopup.OKButtonClicked += (sender, e) =>
                                                    {
                                                        _renameAssemblyPopup.StaysOpen = true;
                                                        if (RenameAssembly
                                                            ((SolutionViewModel.AssemblyModel)
                                                             _renameAssemblyPopup.ItemToRename,
                                                             _renameAssemblyPopup.NewName))
                                                            _renameAssemblyPopup.IsOpen = false;
                                                        //else
                                                        //    _renameAssemblyPopup.IsOpen = true;
                                                        _renameAssemblyPopup.StaysOpen = false;
                                                    };
            _newAssemblyPopup = new NewItemPopup();
            _newAssemblyPopup.OKButtonClicked += (sender, e) =>
                                                 {
                                                     if (CreateAssembly(_newAssemblyPopup.NewItemName))
                                                         _newAssemblyPopup.IsOpen = false;
                                                     else

                                                         _newAssemblyPopup.IsOpen = true;
                                                 };
        }

        private void RemoveAssemblyView(SolutionViewModel.AssemblyModel assemblyModel)
        {
            SolutionAssemblyView assemblyViewToRemove = _assemblyViews.Find(view => view.Model == assemblyModel);
            if (assemblyViewToRemove == null) return;

            AssembliesStackPanel.Children.Remove(assemblyViewToRemove);
            _assemblyViews.Add(assemblyViewToRemove);
        }

        private void AddAssemblyView(SolutionViewModel.AssemblyModel assemblyModel)
        {
            SolutionAssemblyView assemblyView = new SolutionAssemblyView();
            ContextMenu contextMenu = new ContextMenu();

            MenuItem deleteMenuItem = new MenuItem();
            deleteMenuItem.Header = "Delete";
            deleteMenuItem.Click += (sender, e) => DeleteAssembly(assemblyModel);
            contextMenu.Items.Add(deleteMenuItem);

            MenuItem renameMenuItem = new MenuItem();
            renameMenuItem.Header = "Rename";
            renameMenuItem.Click += (sender, e) => PopupRenameAssembly(assemblyModel);
            contextMenu.Items.Add(renameMenuItem);

            MenuItem newAssemblyMenuItem = new MenuItem();
            newAssemblyMenuItem.Header = "New Assembly";
            newAssemblyMenuItem.Click += (sender, e) => PopupNewAssembly();
            contextMenu.Items.Add(newAssemblyMenuItem);

            assemblyView.ContextMenu = contextMenu;

            AssembliesStackPanel.Children.Add(assemblyView);

            _assemblyViews.Add(assemblyView);
            assemblyView.Init(Controller, assemblyModel);
            if (Model.CurrentAssembly == assemblyModel) assemblyView.IsSelected = true;
        }


        public ISolutionViewController Controller { get; private set; }
        public SolutionViewModel Model { get; private set; }

        public StackPanel AssembliesStackPanel
        {
            get { return _assembliesStackPanel; }
        }

        private void PopupRenameAssembly(SolutionViewModel.AssemblyModel assemblyModel)
        {
            _renameAssemblyPopup.Init(assemblyModel, "Assembly", assemblyModel.Name);
            _renameAssemblyPopup.IsOpen = true;
        }

        private void PopupNewAssembly()
        {
            _newAssemblyPopup.Init("Assembly");
            _newAssemblyPopup.IsOpen = true;
        }

        public bool CreateAssembly(string assemblyName)
        {
            if (String.IsNullOrEmpty(assemblyName)) return false;
            try
            {
                Controller.CreateAssembly(assemblyName);
                return true;
            }
            catch (HabaneroApplicationException ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify
                    (ex, "Problem creating assembly '" + assemblyName + "'", "Note:");
            }
            return false;
        }


        public void DeleteAssembly(SolutionViewModel.AssemblyModel assemblyModel)
        {
            try
            {
                Controller.DeleteAssembly(assemblyModel);
            }
            catch (HabaneroApplicationException ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify
                    (ex, "Problem deleting assembly '" + assemblyModel.Name + "'", "Note:");
            }
        }

        public bool RenameAssembly(SolutionViewModel.AssemblyModel assemblyModel, string newName)
        {
            try
            {
                Controller.RenameAssembly(assemblyModel, newName);
                return true;
            }
            catch (HabaneroApplicationException ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify
                    (ex, "Problem renaming assembly '" + assemblyModel.Name + "'", "Note:");
            }
            return false;
        }
    }
}